package com.xisoft.generator.service.impl;

import com.xisoft.common.db.SqlHelper;
import com.xisoft.common.pubEnv.PubEnvUtil;
import com.xisoft.common.pubEnv.StringUtil;
import com.xisoft.generator.config.TemplateConfig;
import com.xisoft.generator.entity.BaseModel;
import com.xisoft.generator.entity.Column;
import com.xisoft.generator.entity.Table;
import com.xisoft.generator.handle.*;
import com.xisoft.generator.mapper.SysGeneratorMapper;
import com.xisoft.generator.service.ISysGenService;
import com.xisoft.generator.utils.ResultEntity;
import com.xisoft.utils.SpringHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;

/**
 * *
 * Created with Description:
 *
 * @version 1.0 <br>
 * @packagename: com.xisoft.generator.service.impl<br>
 * @author: LiBencheng <br>
 * @computer: licheng <br>
 * @date: Created on 2022/8/9 13:56 <br>
 */
@Service ("SysGenServiceImpl")
public class SysGenServiceImpl implements ISysGenService
{
    @Autowired
    TemplateConfig templateConfig;
    private String TABLE = "table";
    private String NAME = "name";
    private String CHILD = "child";

    //{"table":{"name":"hr_salary_data","child":[{"table":{"name":"hr_salary_data_details"}}]}}
    @Override public ResultEntity create(Map< String,Object > valMap)
    {
        ResultEntity resultEntity = new ResultEntity();
        Map< String,Object > tableMap = (Map< String,Object >) valMap.get(TABLE);
        String tableName = StringUtil.valueOf(tableMap.get(NAME));


        BaseModel model = getBaseModel(tableName);
        List< BaseModel > modelList = new LinkedList();

        List< Map< String,Object > > childList = (List< Map< String,Object > >) tableMap.get(CHILD);
        childList.stream().forEach(map ->
                                   {
                                       String tabName =
                                               StringUtil.valueOf(((Map< String,Object >) map.get(TABLE)).get(NAME));

                                       StringBuilder voName = new StringBuilder();
                                       String[] strs = tabName.split(PubEnvUtil.UNDERSCORE);
                                       for (int i = 1; i < PubEnvUtil.getSize(strs); i++)
                                       { voName.append(StringUtil.firstCharUpperCase(strs[i])); }
                                       System.out.println(voName);
                                       // model.getTable().getChilds().add(StringUtil.valueOf(voName));

                                       modelList.add(getBaseModel(tableName));
                                   });

        HandlerChain handlerChain = new HandlerChainImp();
        handlerChain.addHandler(new CheckHandler());
        // handlerChain.addHandler(new DBHandler());
        handlerChain.addHandler(new TempldateHandler());
        handlerChain.handle(model);
        modelList.stream().forEach(cModel ->
                                   {
                                       handlerChain.handle(cModel);
                                   });

        return resultEntity;
    }

    BaseModel getBaseModel(String tableName)
    {
        BaseModel model = new BaseModel();
        model.templateConfig = this.templateConfig;
        model.base_path = this.templateConfig.BASE_PATH;
        model.tablename = tableName.trim();
        model.basePackageName = this.templateConfig.BASEPACKAGENAME;
        model.author = this.templateConfig.AUTHOR;
        model.setTable(getTable(model));

        return model;

    }

    private Table getTable(BaseModel model) throws RuntimeException
    {
        AtomicReference< Table > table = new AtomicReference<>();

        List< Table > tableList = SpringHelper.getBean(SysGeneratorMapper.class).getTableInfo(getTableName(model));
        if (PubEnvUtil.getSize(tableList) < 1)
        { throw new RuntimeException("您输入的表名 【" + model.tablename + "】，在url【config/db.setting】数据源中不存在"); }
        table.set(tableList.get(0));
        AtomicReference< String > primaryKey = new AtomicReference<>();

        // List< Column > columnList = Db.use().query(SqlHelper.getColumnByTableNameOrcl(model.tablename), Column.class);
        List< Column > columnList =
                SpringHelper.getBean(SysGeneratorMapper.class)
                            .getColumnList(SqlHelper.getColumnByTableOrcl(model.tablename));
        columnList.forEach(col ->
                           {
                               if (!Column.ignoreColumns.toLowerCase().contains(col.getvName().toLowerCase()))
                               {
                                   col.setPrimary(false);
                                   // if (PubEnvUtil.equals(PubEnvUtil.ONE, col.pk))
                                   { col.setPrimary(true); }
                                   col.setVtypeByDType();
                                   col.setXmlTypeByDtype();
                                   // col.setCOMMENTS(StringUtil.valueOfNull(col.getCOMMENTS()));
                                   // col.setUNICODE_COMMENTS(StringUtil.chinaToUnicode(col.getCOMMENTS()));
                                   table.get().getColumns().add(col);
                               }
                           });

        return table.get();
    }

    protected String getTableName(BaseModel model)
    {
        StringBuilder sql1 = new StringBuilder();
        sql1.append(" SELECT t.table_name AS \"dname\",");
        sql1.append(" replace(initcap(lower(substr(t.table_name, instr(t.table_name, '_')))), '_', '') AS \"vname\",");
        sql1.append(" t.table_type AS \"table_type\",");
        sql1.append(" nvl(t.comments, '.') AS \"comments\"");
        sql1.append(" FROM user_tab_comments t");
        sql1.append(" WHERE (t.table_name = '");
        sql1.append(model.tablename.toLowerCase());
        sql1.append("'OR t.table_name = '");
        sql1.append(model.tablename.toUpperCase()).append("') ");

        return sql1.toString();
    }
}
